/*
 * SurfaceUtils.cpp
 *
 *  Created on: Apr 15, 2012
 *      Author: gonzalo
 */

#define Maximum(a, b) ((a > b) ? a : b)
#define Minimum(a, b) ((a < b) ? a : b)

#include "SurfaceUtils.h"
#include "math.h"
#include "../lib/SDL_rotozoom.h"
#include "SDL/SDL_image.h"

#include "../Constantes.h"

Parcel* SurfaceUtils::getBoundaries(SDL_Surface* surface){
	if(surface == NULL)
		return NULL;

	Parcel* parcela = new Parcel();
	parcela->posX = surface->clip_rect.x;
	parcela->posY = surface->clip_rect.y;
	parcela->width = surface->w;
	parcela->height = surface->h;

	return parcela;
}


SDL_Surface* SurfaceUtils::resizeSurface(float newWidth, float newHeigth, SDL_Surface* originalSurface){

	if(originalSurface == NULL)
		return NULL;

    float width_image=(float)(originalSurface->w);
    float heigth_image=(float)(originalSurface->h);

    float zoomX = (newWidth/width_image);
    float zoomY = (newHeigth/heigth_image);

	return rotozoomSurfaceXY(originalSurface,0,zoomX,zoomY,0);
}


SDL_Surface* SurfaceUtils::loadImage(std::string path){

	if(!FileChecker::fileExists(path)){
		Logger::log("SurfaceUtils","loadImage","El archivo no existe!. File:" + path);
		return NULL;
	}

	SDL_Surface* surface = NULL;

	SDL_Surface* aux = NULL;
	char* c_path = new char[path.size() + 1];
	c_path[0] = '\0';
	strcpy	(c_path, path.c_str());
	aux = IMG_Load(c_path);
	delete[] c_path;

	if (aux != NULL) {
        //Create an optimized surface
		surface = SDL_DisplayFormat( aux );
		//surface = SDL_DisplayFormatAlpha(aux);
		SDL_FreeSurface(aux);
	}

	return surface;

}

SDL_Surface* SurfaceUtils::renderText(std::string message,TTF_Font* font){

	if (font == NULL) {
		Logger::log("SurfaceUtils", "renderText", "No se pudo inicializar la fuente");
		return NULL;
	}

	//TODO agregarle la posibilidad del Color
	SDL_Color textColor;
	textColor.r = 0;
	textColor.g = 0;
	textColor.b = 0;

	SDL_Surface* renderedText = TTF_RenderText_Solid(font, message.c_str(),textColor);

	return renderedText;
}

SDL_Surface* SurfaceUtils::renderText(std::string message,TTF_Font* font,int r, int g, int b){

	if (font == NULL) {
		Logger::log("SurfaceUtils", "renderText", "No se pudo inicializar la fuente");
		return NULL;
	}

	SDL_Color textColor;
	textColor.r = r;
	textColor.g = g;
	textColor.b = b;

	SDL_Surface* renderedText = TTF_RenderText_Solid(font, message.c_str(),textColor);

	return renderedText;
}

SDL_Surface* SurfaceUtils::renderText(std::string message,int ptSize){
	TTF_Font* font = TTF_OpenFont(DEFAULT_FONT, ptSize);

	SDL_Surface* renderedText = SurfaceUtils::renderText(message,font);

	TTF_CloseFont(font);

	return renderedText;
}

SDL_Surface* SurfaceUtils::renderText(std::string message, int ptSize, int r,
		int g, int b){
	TTF_Font* font = TTF_OpenFont(DEFAULT_FONT, ptSize);

	SDL_Surface* renderedText = SurfaceUtils::renderText(message,font,r,g,b);

	TTF_CloseFont(font);

	return renderedText;
}

SDL_Surface* SurfaceUtils::renderText(std::string message){
	TTF_Font* font = TTF_OpenFont(DEFAULT_FONT, DEFAULT_FONT_SIZE);

	SDL_Surface* renderedText = SurfaceUtils::renderText(message,font);

	TTF_CloseFont(font);

	return renderedText;
}


SDL_Surface* SurfaceUtils::colorSurface(int width,int height,Color color){
	SDL_Surface * surface =
			SDL_CreateRGBSurface(SDL_SWSURFACE,width, height, GAME_COLOR_DEPTH, 0,0,0,0x00000000);

	SDL_FillRect(surface, &surface->clip_rect,color.getColor());

	return surface;
}

SDL_Surface* SurfaceUtils::transparentSurface(int width,int height){
	SDL_Surface * surface =
			SDL_CreateRGBSurface(SDL_SWSURFACE,width, height, GAME_COLOR_DEPTH, 0,0,0,0x00000000);

	SDL_SetAlpha(surface, SDL_SRCALPHA, 50);

	return surface;
}

SDL_Rect SurfaceUtils::intersection(const SDL_Rect& boundsA, const SDL_Rect& boundsB){
	int x1 = Maximum(boundsA.x, boundsB.x);
	int y1 = Maximum(boundsA.y, boundsB.y);
	int x2 = Minimum(boundsA.x + boundsA.w, boundsB.x + boundsB.w);
	int y2 = Minimum(boundsA.y + boundsA.h, boundsB.y + boundsB.h);

	int width = x2 - x1;
	int height = y2 - y1;

	if(width > 0 && height > 0)
	{
		SDL_Rect intersect = {x1, y1, width, height};
		return intersect;
	}
	else
	{
		SDL_Rect intersect = {0, 0, 0, 0};
		return intersect;
	}
}


bool SurfaceUtils::getAlphaXY(SDL_Surface* surface, int x, int y){
	int bpp = surface->format->BytesPerPixel;
	Uint8* p = (Uint8*)surface->pixels + y * surface->pitch + x * bpp;
	Uint32 pixelColor;

	switch(bpp)
	{
		case(1):
			pixelColor = *p;
			break;
		case(2):
			pixelColor = *(Uint16*)p;
			break;
		case(3):
			if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
				pixelColor = p[0] << 16 | p[1] << 8 | p[2];
			else
				pixelColor = p[0] | p[1] << 8 | p[2] << 16;
			break;
		case(4):
			pixelColor = *(Uint32*)p;
			break;
	}

	Uint8 red, green, blue, alpha;
	SDL_GetRGBA(pixelColor, surface->format, &red, &green, &blue, &alpha);

	return alpha > 200;
}
